﻿using System;
using System.Collections.Generic;
using TableDef;
using UnityEngine;
using UnityEngine.UI;

namespace Share
{
    /*
    层级数据，
    每一个层级都会有个显示的列表[m_UIList]和缓存列表[m_TmpList]，
    每次开启窗口的时候，如果缓存列表里有，就会从缓存列表里取出，放到显示列表里，如果没有，创建一个，放到缓存列表里，然后在去除放到显示列表里
    关闭窗口的时候，判断窗口是否需要缓存，如果需要，就放回缓存列表，否则就直接删除
    */
    public class UICore
    {
        public UICore(int nZero)
        {
            m_nLayerZero = nZero;
            m_UIList = new List<PanelBase>();
        }

        int m_nLayerZero; // 这个组的初始层数
        List<PanelBase> m_UIList;  // 这层所显示的界面的列表

        /// <summary>
        /// 获取当前层级最顶部的窗口
        /// </summary>
        /// <returns>返回当前层级最顶部的PanelBase对象，如果没有则返回null</returns>
        public PanelBase GetTopWindow()
        {
            PanelBase win = null;
            foreach (var item in m_UIList)
            {
                if (item.IsLogicWindow && item.IsShown)
                {
                    if (win == null)
                    {
                        win = item;
                        continue;
                    }
                    if (win.SortOrder < item.SortOrder)
                        win = item;
                }
            }
            return win;
        }
        public void GetFullWindow(ref List<PanelBase> list)
        {
            foreach (var item in m_UIList)
            {
                if (item.IsShown && item.IsFullWindow())
                {
                    list.Add(item);
                }
            }
        }

        public void DoReleaseAll()
        {
            foreach (var item in m_UIList)
            {
                item.gameObject.StopOrDestroy();
            }
            m_UIList.Clear();
        }

        // 隐藏本层所有窗口，一般用来关闭主界面和关闭所有弹出式界面
        public void DoCloseAll()
        {
            ClearNullWindow();
            foreach (var item in m_UIList)
            {
                item.DoClose();
            }
        }

        /// <summary>
        /// 显示本层所有隐藏的窗口
        /// </summary>
        public void DoShowAll()
        {
            ClearNullWindow();
            foreach (var item in m_UIList)
            {
                item.DoShow();
            }
        }



        public PanelBase GetWindow(string strName)
        {
            foreach (var item in m_UIList)
            {
                if (item.PanelName == strName)
                {
                    return item;
                }
            }
            return null;
        }

        /// <summary>
        /// 是否窗口存在，无论是不是显示
        /// </summary>
        /// <param name="strWindowName">窗口名称</param>
        /// <returns>如果存在返回true，否则返回false</returns>
        public bool IsWindowExist(string strWindowName)
        {
            foreach (var item in m_UIList)
            {
                if (item.PanelName == strWindowName)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 创建新窗口并初始化
        /// </summary>
        /// <param name="windowName">窗口名称</param>
        /// <param name="callback">创建完成后的回调</param>
        void CreateWindow(string windowName, Action<PanelBase> callback = null)
        {
            var data = UIMgr.Instance.GetTableDataByName(windowName);
            var addressPath = data.m_strPrefabPath;
            try
            {
                var window = ObjectMgr.Instance.CreateObj(addressPath);
                if (window != null)
                {
                    DoInitPanel(windowName, window, data, callback);
                }
                else
                {
                    XKLog.LogError("CreateWindow error:" + windowName);
                    callback?.Invoke(null);
                }
            }
            catch (Exception e)
            {
                XKLog.LogError("CreateWindow error:[{0}]    -->     message = [{1}]", windowName, e.Message);
            }
        }

        /// <summary>
        /// 初始化面板
        /// </summary>
        void DoInitPanel(string panelName, GameObject panelObj, t_windowdef data, Action<PanelBase> callback = null)
        {
            if (panelObj == null)
            {
                XKLog.LogError("没有找到 界面路径:" + data.m_strPrefabPath);
                callback?.Invoke(null);
                return;
            }

            PanelBase panelBase = panelObj.GetComponent<PanelBase>();
            panelBase.ResData = data;
            var scaler = panelObj.GetComponent<CanvasScaler>();
            scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
            scaler.referenceResolution = TypeDefine.UIScreenSize;
            panelBase.Canvas = panelBase.GetComponent<Canvas>();
            panelBase.Canvas.renderMode = RenderMode.ScreenSpaceOverlay;
            panelBase.Canvas.worldCamera = UIMgr.Instance.m_uiCamera2d;
            panelBase.PanelName = panelName;

            panelObj.transform.SetParent(UIMgr.Instance.m_UIRoot);
            RectTransform rectTrans = panelObj.transform as RectTransform;
            rectTrans.localPosition = Vector3.zero;
            rectTrans.localScale = Vector3.one;
            panelObj.gameObject.SetActive(true);

            callback?.Invoke(panelBase);

        }

        // 清理掉无效窗口
        void ClearNullWindow()
        {
            for (int i = 0; i < m_UIList.Count;)
            {
                if (m_UIList[i] == null)
                    m_UIList.RemoveAt(i);
                else
                    ++i;
            }
        }

        // 根据名字得到窗口
        public void OpenWindowByName(string strName, bool bCreateIfExist = true, Action<PanelBase> _callBack = null)
        {
            var item = GetWindow(strName);
            if (item != null)
            {
                _callBack?.Invoke(item);
                return;
            }
            else
            {
                if (bCreateIfExist)
                {
                    CreateWindow(strName, (window) =>
                    {
                        _callBack?.Invoke(window);
                    });
                    return;
                }
            }
            _callBack?.Invoke(null);
            return;
        }

        public void DoOpenWindowExit(string strName, EventParam param = null)
        {
            if (IsWindowExist(strName))
            {
                OpenWindowByName(strName, false, (window) =>
                {
                    window.DoShow(param);
                });
            }
            else
            {
                DoOpenWindow(strName, param);
            }
        }

        // 显示窗口，需要这个窗口下的界面进行排序
        public void DoOpenWindow(string strName, EventParam param = null, Action<PanelBase> _callBack = null)
        {
            // 如果窗口已经存在
            if (IsWindowExist(strName))
            {
                var win = GetWindow(strName);
                if (win)
                {
                    if (win.UIGroup >= 0)
                    {
                        UIMgr.Instance.DoCloseWindowByGroup(win.UIGroup, win);
                    }
                    win.DoShow(param);
                    win.DoPlayBGM();
                    DoResortWindow();
                    _callBack?.Invoke(win);
                    return;
                }
            }

            ClearNullWindow();
            // 如果不存在，就来个新的
            OpenWindowByName(strName, true, (window) =>
            {
                if (window)
                {
                    if (window.UIGroup >= 0)
                    {
                        UIMgr.Instance.DoCloseWindowByGroup(window.UIGroup, window);
                    }
                    window.DoShow(param);
                    window.DoPlayBGM();
                    window.Parent = this;
                    m_UIList.Add(window);
                    XKLog.Log(" Open Window Success!!!!     [" + strName + "]");
                    var cmd = new EventParamCommon();
                    cmd.AddData("window", strName);
                    EventMgr.Instance.TriggerEvent((int)SystemEventDef.System_Open_Window, cmd);
                    _callBack?.Invoke(window);
                }
            });
        }

        // 关闭指定互斥组的界面
        public void DoCloseWindowByGroup(long nGroup, PanelBase exp)
        {
            // 边界条件检查
            if (m_UIList == null || m_UIList.Count == 0)
            {
                return;
            }

            // 创建一个临时列表，用于存储需要移除的UI对象
            List<PanelBase> toRemove = new List<PanelBase>();

            try
            {
                // 遍历所有UI对象，找到属于指定组的UI对象
                foreach (var ui in m_UIList)
                {
                    if (ui.UIGroup == nGroup)
                    {
                        try
                        {
                            if (ui != exp)
                                toRemove.Add(ui); // 标记为需要移除
                        }
                        catch (Exception ex)
                        {
                            // 记录异常信息，但继续处理其他窗口
                            XKLog.LogError($"Failed to close UI with group {nGroup}: {ex.Message}");
                        }
                    }
                }

                // 统一移除标记的UI对象
                foreach (var ui in toRemove)
                {
                    m_UIList.Remove(ui);
                    ui.DoDestory();
                }
                DoResortWindow();
            }
            catch (Exception ex)
            {
                // 处理外部异常
                XKLog.LogError($"Error occurred while closing windows by group {nGroup}: {ex.Message}");
            }
        }

        public void DoCloseWindow(PanelBase win)
        {
            if (win != null)
            {
                m_UIList.Remove(win);
                win.DoDestory();
                DoResortWindow();
            }
        }
        // 关闭窗口
        public bool DoCloseWindow(string strName)
        {
            var win = GetWindow(strName);
            if (win != null)
            {
                m_UIList.Remove(win);
                win.DoDestory();
                DoResortWindow();
                return true;
            }
            return false;
        }
        public bool DoHideWindow(string strName)
        {
            var win = GetWindow(strName);
            if (win != null)
            {
                win.DoHide();
                return true;
            }
            return false;
        }

        // 对窗口重新排序
        public void DoResortWindow()
        {
            for (int i = 0; i < m_UIList.Count; ++i)
            {
                if (m_UIList[i] != null && m_UIList[i].IsShown)
                {
                    m_UIList[i].DoResetOrder(m_nLayerZero + i * 10 + 1);
                }
            }
        }
    }
}
